﻿using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Xml.Serialization;
using PrearrangedChaos.AgileZen.Service.Rest;

namespace PrearrangedChaos.AgileZen.Service.Model
{
    /// <remarks/>
    [XmlTypeAttribute(AnonymousType = true)]
    [XmlRoot(ElementName = "story", Namespace = "", IsNullable = false)]
    [ZenRestRequest("projects/{ProjectId}/stories/{StoryId}", "projects/{ProjectId}/stories")]
    public partial class Story : StoryUpdater, IStory
    {
        private IUser _creator;
        private IProject _project;
        private IComment[] _comments;
        private IMilestone[] _milestones;
        private IStep[] _steps;
        private ITask[] _tasks;
        private ITag[] _tags;

        /// <remarks/>
        [XmlElement(ElementName = "creator")]
        public User CreatorXmlElement
        {
            get { return _creator as User; }
            set
            {
                _creator = value;
                this.Unmodified("creator");
            }
        }

        [XmlIgnore]
        public IUser Creator
        {
            get { return _creator; }
            set
            {
                if (_creator == value)
                    return;

                _creator = value;
                this.Modified("creator");
            }
        }

        public bool CreatorXmlElementSpecified { get { return this.IsModified("creator"); } }

        /// <remarks/>
        [XmlElement(ElementName = "project")]
        public Project ProjectXmlElement
        {
            get { return _project as Project; }
            set { _project = value; }
        }

        /// <remarks/>
        [XmlIgnore]
        public IProject Project
        {
            get { return _project; }
            set { _project = value; }
        }

        public bool ProjectXmlElementSpecified { get { return false; } }

        [XmlArrayItemAttribute("comment", IsNullable = false)]
        [XmlArray(ElementName = "comments")]
        public Comment[] CommentXmlElement
        {
            get { return _comments as Comment[]; }
            set { _comments = value; }
        }

        [XmlIgnore]
        public ReadOnlyCollection<IComment> Comments
        {
            get { return new ReadOnlyCollection<IComment>(_comments ?? new Comment[0]); }
        }

        public bool CommentXmlElementSpecified { get { return false; } }

        /// <remarks/>
        [XmlElement(ElementName = "metrics")]
        public StoryMetrics MetricsXmlElement
        {
            get { return Metrics as StoryMetrics; }
            set { Metrics = value; }
        }

        /// <remarks/>
        [XmlIgnore]
        public IStoryMetrics Metrics { get; set; }

        public bool MetricsXmlElementSpecified { get { return false; } }

        [XmlArrayItemAttribute("milestone", IsNullable = false)]
        [XmlArray(ElementName = "milestones")]
        public Milestone[] MilestonesXmlElement
        {
            get { return _milestones as Milestone[]; }
            set { _milestones = value; }
        }

        [XmlIgnore]
        public ReadOnlyCollection<IMilestone> Milestones
        {
            get { return new ReadOnlyCollection<IMilestone>(_milestones ?? new Milestone[0]); }
        }

        public bool MilestonesXmlElementSpecified { get { return false; } }

        [XmlArrayItemAttribute("step", IsNullable = false)]
        [XmlArray(ElementName = "steps")]
        public Step[] StepsXmlElement
        {
            get { return _steps as Step[]; }
            set { _steps = value; }
        }

        [XmlIgnore]
        public ReadOnlyCollection<IStep> Steps
        {
            get { return new ReadOnlyCollection<IStep>(_steps ?? new Step[0]); }
        }

        public bool StepsXmlElementSpecified { get { return false; } }

        [XmlArrayItemAttribute("tag", IsNullable = false)]
        [XmlArray(ElementName = "tags")]
        public Tag[] TagsXmlElement
        {
            get { return _tags as Tag[]; }
            set
            {
                _tags = value;
                this.Unmodified("tags");
            }
        }

        [XmlIgnore]
        public ReadOnlyCollection<ITag> Tags
        {
            get { return new ReadOnlyCollection<ITag>(_tags ?? new Tag[0]); }
        }

        internal Tag[] TagsInternal
        {
            set
            {
                if (_tags == value)
                    return;

                _tags = value;
                this.Modified("tags");
            }
        }

        public bool TagsXmlElementSpecified { get { return this.IsModified("tags"); } }

        [XmlArrayItemAttribute("task", IsNullable = false)]
        [XmlArray(ElementName = "tasks")]
        public Task[] TasksXmlElement
        {
            get { return _tasks as Task[]; }
            set
            {
                _tasks = value;
                this.Unmodified("tasks");
            }
        }

        [XmlIgnore]
        public ReadOnlyCollection<ITask> Tasks
        {
            get { return new ReadOnlyCollection<ITask>(_tasks ?? new Task[0]); }
        }

        internal Task[] TasksInternal
        {
            set
            {
                if (_tasks == value)
                    return;

                _tasks = value;
                this.Modified("tasks");
            }
        }

        public bool TasksXmlElementSpecified { get { return this.IsModified("tasks"); } }

        [XmlIgnore]
        public new StoryColor Color
        {
            get { return base.Color == null ? default(StoryColor) : base.Color.Value; }
            set { base.Color = value; }
        }

        [XmlIgnore]
        public new StoryStatus Status
        {
            get { return base.Status == null ? default(StoryStatus) : base.Status.Value; }
            set { base.Status = value; }
        }

    }
}
